/**
 * 
 */
package wpmp.auth.service;

import java.util.UUID;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.stereotype.Component;

import wpmp.auth.Statics;
import wpmp.auth.cache.CacheManager;
import wpmp.auth.dao.UserDao;
import wpmp.utils.quickbean.User;

/**
 * @author Wayne.Wang<5waynewang@gmail.com>
 * @since 3:29:24 PM Dec 26, 2012
 */
@Component
public class UserService extends BaseService {

	@Autowired
	private CacheManager cacheManager;

	private UserDao dao;

	public UserDao getDao() {
		return dao;
	}

	@Autowired
	public void setDao(UserDao dao) {
		this.dao = dao;
	}

	public User getByLoginName(String loginName) {
		return dao.queryForObject(loginName);
	}

	public User login(String loginName, String password) {
		return this.login(loginName, password, null);
	}

	/**
	 * <pre>
	 * 用户登录
	 * </pre>
	 * 
	 * @param loginName 用户名
	 * @param password 密码，base64编码
	 * @param expDays 失效天数
	 * @return
	 */
	public User login(String loginName, String password, Integer expDays) {
		final SqlRowSet rs = dao.queryForRowSet(loginName);
		if (!rs.next()) {
			return null;
		}

		final String dbPassword = rs.getString("password");

		final String pwd = new String(Base64.decodeBase64(password));

		// 比对md5
		if (!StringUtils.equals(dbPassword, DigestUtils.md5Hex(pwd))) {
			// 登录失败
			return null;
		}

		final String securityId = UUID.randomUUID().toString().replaceAll("-", "");

		final User user = dao.toBean(rs);
		user.setSecurityId(securityId);

		final String key = Statics.USER_ + securityId;

		// 放入缓存，默认失效时间12个小时
		cacheManager.set(key, (expDays == null ? 12 : (expDays * 24)) * 60 * 60, user);

		return user;
	}

	/**
	 * 登出
	 * 
	 * @param loginName
	 * @param password
	 * @return
	 */
	public boolean logout(String loginName, String securityId) {
		final String key = Statics.USER_ + securityId;
		final User user = (User) cacheManager.get(key);

		if (user == null) {
			log.warn("can not find User from Cache by securityId[{}]", securityId);
			return false;
		}

		if (!user.getLoginName().equals(loginName)) {
			log.warn("invalid request, loginName[{}] can not match [{}] from Cache by securityId[{}]", loginName,
					user.getLoginName(), securityId);
			return false;
		}

		cacheManager.delete(Statics.USER_PERMISSION_ + securityId);
		cacheManager.delete(Statics.USER_VIEW_ + securityId);

		return cacheManager.delete(key);
	}

	/**
	 * 校验用户是否已登录
	 * 
	 * @param securityId
	 * @return
	 */
	public boolean check(String securityId) {
		final String key = Statics.USER_ + securityId;
		return cacheManager.get(key) != null;
	}

	/**
	 * 更改密码
	 * 
	 * @param loginName
	 * @param oldPwd
	 * @param newPwd
	 * @param securityId
	 * @return
	 */
	public int updatePassword(String loginName, String oldPwd, String newPwd, String securityId) {
		final String key = Statics.USER_ + securityId;
		final User user = (User) cacheManager.get(key);
		if (user == null) {
			return 400;
		}
		if (!StringUtils.equals(user.getLoginName(), loginName)) {
			return 500;
		}
		final String pwd = dao.getPasswordByLoginName(loginName);

		final String passwd = new String(Base64.decodeBase64(oldPwd));
		// md5 比对
		if (!StringUtils.equals(DigestUtils.md5Hex(passwd), pwd)) {
			return 501;
		}

		final String newPasswd = new String(Base64.decodeBase64(newPwd));

		final int result = dao.updatePassword(loginName, DigestUtils.md5Hex(newPasswd));
		return result > 0 ? 200 : 300;
	}
}
